package ucd.csi.comp30220.fall2011.oteop.flight;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.List;

import ucd.csi.comp30220.fall2011.oteop.flight.impl.FlightStatusPublisher;

public class FlightStatusSubscriber {
    
    private List<FlightStatusListener> listeners = new ArrayList<FlightStatusListener>();
    
    private MulticastSocket socket;
    private Thread thread;
    
    public FlightStatusSubscriber() throws Exception {
        socket = new MulticastSocket(FlightStatusPublisher.BROADCAST_PORT);
        socket.joinGroup(InetAddress.getByName(
                FlightStatusPublisher.BROADCAST_ADDRESS));
        
        thread = new Thread(
            new Runnable() {
                public void run() {
                    receive();
                }
            });
        thread.start();
    }
    
    public void addListener(FlightStatusListener listener) {
        listeners.add(listener);
    }
    
    public void stop() {
        thread.interrupt();
    }
    
    private void fireOnStatusUpdate(FlightStatus status) {
        for (FlightStatusListener listener : listeners) 
            listener.onStatusUpdate(status);
    }
    
    private void receive() {
        while (!thread.isInterrupted()) {
            byte[] buf = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            try {
                socket.receive(packet);
                ByteArrayInputStream bais = new ByteArrayInputStream(buf);
                ObjectInputStream ois = new ObjectInputStream(bais);
                fireOnStatusUpdate((FlightStatus) ois.readObject());
            } catch (Exception e) {
                // swallow it, go round again?
                e.printStackTrace();
                break;
            }
        }
    }

}
